package net.butfly.bus.server;

import java.io.InputStream;

import net.butfly.albacore.exception.SystemException;
import net.butfly.bus.Constants;
import net.butfly.bus.Constants.FilterSide;
import net.butfly.bus.Request;
import net.butfly.bus.Response;
import net.butfly.bus.config.Config;
import net.butfly.bus.config.loader.ClasspathConfigLoad;
import net.butfly.bus.config.parser.XMLConfigParser;
import net.butfly.bus.filter.FilterChain;
import net.butfly.bus.filter.InvokerFilter;
import net.butfly.bus.policy.Router;
import net.butfly.bus.policy.RouterBase;
import net.butfly.bus.policy.SimpleRouter;

public class Server {
	private final String serverId;
	private Config config;

	private FilterChain chain;
	private Router router;

	public Server(String configLocation) {
		this.initialize(configLocation);
		this.config = parser.parse();
		this.router = RouterBase.createRouter(this.config);
		if (this.router == null)
			this.router = new SimpleRouter(this.config);
		this.chain = new FilterChain(config.getFilterBeanList(), new InvokerFilter(this.config, this.router), FilterSide.SERVER);
		this.serverId = this.config.getBusID();
	}

	public String getServerId() {
		return this.serverId;
	}

	public Response execute(Request request) throws Exception {
		if (request == null)
			throw new SystemException(Constants.UserError.BAD_REQUEST, "交易请求不能为空!");
		if (request.code() == null || "".equals(request.code().trim()))
			throw new SystemException(Constants.UserError.BAD_REQUEST, "交易码不能为空！");
		if (request.version() == null || "".equals(request.version().trim()))
			throw new SystemException(Constants.UserError.BAD_REQUEST, "交易版本号不能为空！");
		Response response = new Response();
		chain.execute(request, response);
		return response;
	}

	public Config getConfig() {
		return this.config;
	}

	private ClasspathConfigLoad loader;
	private XMLConfigParser parser;

	private void initialize(String configLocation) {
		this.loader = new ClasspathConfigLoad(configLocation);
		InputStream is = loader.load();
		// load local / internal config
		if (null == is) {
			loader = new ClasspathConfigLoad(Constants.Configuration.DEFAULT_SERVER_CONFIG);
			is = loader.load();
			if (null == is) {
				loader = new ClasspathConfigLoad(Constants.Configuration.INTERNAL_SERVER_CONFIG);
				is = loader.load();
			}
		}
		if (null == is)
			throw new SystemException(Constants.UserError.CONFIG_ERROR, "Bus configurations invalid: " + configLocation);
		this.parser = new XMLConfigParser(loader.load());
	}
}